using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Data;
using MaskData;

namespace DBProxy
{
	public class DBTreeNodeQuery : ITreeNodeQuery
	{
		private DBConnectionService _DBService = DBConnectionService.Instance();
		/// <summary>
		/// get all tree nodes from db.
		/// </summary>
		/// <returns>the collection of tree nodes</returns>
		public List<NavigateTreeNode> GetTreeNodes()
		{
			List<NavigateTreeNode> TreeNodes = new List<NavigateTreeNode>();
			DataTable table = _DBService.GetDataTable(DBConnectionService.conNavigateTreeNodeTable);

			foreach (DataRow nodeRow in table.Rows)
			{
				String name = nodeRow[DBConnectionService.conNavigateTreeNode_Name].ToString();
				String maskNodeId = nodeRow[DBConnectionService.conNavigateTreeNode_MaskNode].ToString();
				Int32 treeNodeID = (Int32)nodeRow[DBConnectionService.conNavigateTreeNode_ID];
				Int32 parentID = (Int32)nodeRow[DBConnectionService.conNavigateTreeNode_Parent];
				Int32 conditionID = (Int32)nodeRow[DBConnectionService.conNavigateTreeNode_Condition];

				//////////////////////////////////////////////////////////////////////////
				//get condition element
				//////////////////////////////////////////////////////////////////////////
				ConditionElement condition = GetConditionElement(conditionID);

				NavigateTreeNode treeNode = new NavigateTreeNode(name, null, maskNodeId, treeNodeID, parentID);
				treeNode.Condition = condition;
				TreeNodes.Add(treeNode);
			}
			return TreeNodes;
		}
		/// <summary>
		/// get condition element according to condition id
		/// </summary>
		/// <param name="conditionID">condition id</param>
		/// <returns>condition element</returns>
		private ConditionElement GetConditionElement(Int32 conditionID)
		{
			ConditionElement conditon = null;
			if (conditionID != 0)
			{
				String sqlString = "select * from "
					+ DBConnectionService.conConditionElementTable
					+ " where "
					+ DBConnectionService.conConditionElement_ConditionID
					+ " = "
					+ conditionID.ToString();
				DataTable table = _DBService.GetDataTable(sqlString, 
					DBConnectionService.conConditionElementTable);
				if (table.Rows.Count == 1)
				{
					DataRow conditionRow = table.Rows[0];
					String fieldID = conditionRow[DBConnectionService.conConditionElement_FieldID].ToString();
					String fieldName = GetFieldNameByID(fieldID);
					String fieldValue = (String)conditionRow[DBConnectionService.conConditionElement_FieldValue];
					Debug.Assert(fieldName != "");
					Int32 OperatorID = (Int32)conditionRow[DBConnectionService.conConditionElement_Operator];

					ConditionOperator oper = GetOperatorByID(OperatorID);
					conditon = new StringCondition(fieldName, oper, fieldValue);
				}
				else if (table.Rows.Count > 1)
				{
					Debug.Assert(false);
				}
			}
			return conditon;
		}

		/// <summary>
		/// get field name from field type table according field id
		/// </summary>
		/// <param name="fieldID">field id</param>
		/// <returns>field name</returns>
		private String GetFieldNameByID(String fieldID)
		{
			String fieldName = "";
			String sqlString = "select * from "
				+ DBConnectionService.conFieldTypeTable
				+ " where "
				+ DBConnectionService.conFieldType_FieldID
				+ " = '"
				+ fieldID.ToString()
				+ "'";
			DataTable table = _DBService.GetDataTable(sqlString,
				DBConnectionService.conFieldTypeTable);

			if (table.Rows.Count == 1)
			{
				DataRow row = table.Rows[0];
				fieldName = row[DBConnectionService.conFieldType_FieldName].ToString();
			}

			return fieldName;
		}
		/// <summary>
		/// get operator object according operator id
		/// </summary>
		/// <param name="OperatorID">operator id</param>
		/// <returns>operator object</returns>
		private ConditionOperator GetOperatorByID(Int32 OperatorID)
		{
			ConditionOperator oper = null;
			switch (OperatorID)
			{
				case DBConnectionService.conBiggerOperator:
					{
						oper = new BiggerOperator();
					}
					break;
				case DBConnectionService.conLessOperatore:
					{
						oper = new LessOperator();
					}
					break;
				case DBConnectionService.conBiggerEqualOperator:
					{
						oper = new BiggerEqualOperator();
					}
					break;
				case DBConnectionService.conLessEqualOperator:
					{
						oper = new LessEqualOperator();
					}
					break;
				case DBConnectionService.conEqualOperator:
					{
						oper = new EqualOperator();
					}
					break;
				case DBConnectionService.conNotEqualOperator:
					{
						oper = new NotEqualOperator();
					}
					break;
				default:
					{
						Debug.Assert(false);
					}
					break;
			}

			return oper;
		}
	}
}
